package com.loukou.lkt.lkt.bo;

import javax.persistence.criteria.*;
import javax.persistence.criteria.CriteriaBuilder.In;

import org.springframework.util.CollectionUtils;

import com.mysql.jdbc.StringUtils;

import java.util.*;

public class Query<T> {
private CriteriaBuilder criteriaBuilder;
private Root<T> from;
private CriteriaQuery<?> cq;
private List<Predicate> predicates = new ArrayList<Predicate>();
public Query(CriteriaBuilder criteriaBuilder,Root<T> root,CriteriaQuery<?> cq){
	this.criteriaBuilder = criteriaBuilder;
	this.from =root;
	this.cq = cq;
}
/**
 * not in
 * 
 * @param propertyName
 *            属性名称
 * @param value
 *            值集合
 */
public void notIn(String propertyName, Collection value) {
    if ((value == null) || (value.size() == 0)) {
        return;
    }
    Iterator iterator = value.iterator();
    In in = criteriaBuilder.in(this.from.get(propertyName));
    while (iterator.hasNext()) {
        in.value(iterator.next());
    }
	this.predicates.add(criteriaBuilder.not(in));
}
/** 相等 */
public void eq(String propertyName, Object value) {
    if (isNullOrEmpty(value))
        return;
    this.predicates.add(criteriaBuilder.equal(from.get(propertyName), value));
}
private boolean isNullOrEmpty(Object value) {
    if (value instanceof String) {
        return value == null || "".equals(value);
    }
    return value == null;
}
public void or(List<String> propertyName, Object value) {
    if (isNullOrEmpty(value))
        return;
    if ((propertyName == null) || (propertyName.size() == 0))
        return;
    Predicate predicate = criteriaBuilder.or(criteriaBuilder.equal(from.get(propertyName.get(0)), value));
    for (int i = 1; i < propertyName.size(); ++i)
        predicate = criteriaBuilder.or(predicate, criteriaBuilder.equal(from.get(propertyName.get(i)), value));
    this.predicates.add(predicate);
}



/** 空 */
public void isNull(String propertyName) {
    this.predicates.add(criteriaBuilder.isNull(from.get(propertyName)));
}

/** 非空 */
public void isNotNull(String propertyName) {
    this.predicates.add(criteriaBuilder.isNotNull(from.get(propertyName)));
}

/** 不相等 */
public void notEq(String propertyName, Object value) {
    if (isNullOrEmpty(value)) {
        return;
    }
    this.predicates.add(criteriaBuilder.notEqual(from.get(propertyName), value));
}

/**
 * 模糊匹配
 * 
 * @param propertyName
 *            属性名称
 * @param value
 *            属性值
 */
public void like(String propertyName, String value) {
    if (isNullOrEmpty(value))
        return;
    if (value.indexOf("%") < 0)
        value = "%" + value + "%";
    Path<String> s = from.get(propertyName);
    this.predicates.add(criteriaBuilder.like(s, value));
}

/**
 * 
 * orlike
 * */
public void orLike(List<String> propertyName, String value) {
    if (isNullOrEmpty(value) || (propertyName.size() == 0))
        return;
    if (value.indexOf("%") < 0)
        value = "%" + value + "%";
    Path<String> s = from.get(propertyName.get(0));
    Predicate predicate = criteriaBuilder.or(criteriaBuilder.like(s, value.toString()));
    for (int i = 1; i < propertyName.size(); ++i)
    	s = from.get(propertyName.get(i));
        predicate = criteriaBuilder.or(predicate, criteriaBuilder.like(s, value));
    this.predicates.add(predicate);
}

/**
 * 
 * orin
 * */
public void orIn(String propertyName,String propertyName1, Collection values,Collection values1) {
    if (CollectionUtils.isEmpty(values) || (StringUtils.isNullOrEmpty(propertyName))||(StringUtils.isNullOrEmpty(propertyName1)))
        return;
    
    Path<String> s = from.get(propertyName);
    
    Iterator iterator = values.iterator();
    Iterator iterator1 = values1.iterator();
    In in = criteriaBuilder.in(s);
    In in1 = criteriaBuilder.in(from.get(propertyName1));
    while (iterator.hasNext()) {
        in.value(iterator.next());
   }
    while (iterator1.hasNext()) {
        in1.value(iterator1.next());
   }
    Predicate predicate = criteriaBuilder.or(in);
    predicate = criteriaBuilder.or(predicate, in1);
    //predicate = criteriaBuilder.or(criteriaBuilder.and(in),criteriaBuilder.and(in1));
    this.predicates.add(predicate);
}
/**
 * orlike 第一个左起始
 * 
 * **/
public void orLike(List<String> propertyName, String value, boolean firstisleft) {
    if (isNullOrEmpty(value) || (propertyName.size() == 0))
        return;
    String value1 = value+"%";
    if (value.indexOf("%") < 0)
        value = "%" + value + "%";
    Path<String> s = from.get(propertyName.get(0));
    Predicate predicate = criteriaBuilder.or(criteriaBuilder.like(s, value1.toString()));
    for (int i = 1; i < propertyName.size(); ++i)
    	s = from.get(propertyName.get(i));
        predicate = criteriaBuilder.or(predicate, criteriaBuilder.like(s, value));
    this.predicates.add(predicate);
}
/**
 * 时间区间查询
 * 
 * @param propertyName
 *            属性名称
 * @param lo
 *            属性起始值
 * @param go
 *            属性结束值
 */
public void between(String propertyName, Date lo, Date go) {
    if (!isNullOrEmpty(lo) && !isNullOrEmpty(go)) {
    	Path<Date> s = from.get(propertyName);
        this.predicates.add(criteriaBuilder.between(s, lo, go));
    }
}

public void between(String propertyName, Number lo, Number go) {
    if (!(isNullOrEmpty(lo)))
        ge(propertyName, lo);

    if (!(isNullOrEmpty(go)))
        le(propertyName, go);
}

public void betweens(String propertyName, Date lo, Date go) {	
	 if (!(isNullOrEmpty(lo))){
		 Path<Date> s = from.get(propertyName);
	    this.predicates.add(criteriaBuilder.greaterThanOrEqualTo(s, lo));
	    }
	 if (!(isNullOrEmpty(go))){
		 Path<Date> s = from.get(propertyName);
	    this.predicates.add(criteriaBuilder.lessThanOrEqualTo(s, go));
	    }
}

/**
 * 小于等于
 * 
 * @param propertyName
 *            属性名称
 * @param value
 *            属性值
 */
public void le(String propertyName, Number value) {
    if (isNullOrEmpty(value)) {
        return;
    }
    Path<Number> s = from.get(propertyName);
    this.predicates.add(criteriaBuilder.le(s, value));
}

/**
 * 小于
 * 
 * @param propertyName
 *            属性名称
 * @param value
 *            属性值
 */
public void lt(String propertyName, Number value) {
    if (isNullOrEmpty(value)) {
        return;
    }
    Path<Number> s = from.get(propertyName);
    this.predicates.add(criteriaBuilder.lt(s, value));
}

/**
 * 大于等于
 * 
 * @param propertyName
 *            属性名称
 * @param value
 *            属性值
 */
public void ge(String propertyName, Number value) {
    if (isNullOrEmpty(value)) {
        return;
    }
    Path<Number> s = from.get(propertyName);
    this.predicates.add(criteriaBuilder.ge(s, value));
}

/**
 * 大于
 * 
 * @param propertyName
 *            属性名称
 * @param value
 *            属性值
 */
public void gt(String propertyName, Number value) {
    if (isNullOrEmpty(value)) {
        return;
    }
    Path<Number> s = from.get(propertyName);
    this.predicates.add(criteriaBuilder.gt(s, value));
}


/**
 * in
 * 
 * @param propertyName
 *            属性名称
 * @param value
 *            值集合
 */
public void in(String propertyName, Collection value) {
    if ((value == null) || (value.size() == 0)) {
        return;
    }
    Iterator iterator = value.iterator();
    In in = criteriaBuilder.in(from.get(propertyName));
    while (iterator.hasNext()) {
        in.value(iterator.next());
    }
    this.predicates.add(in);
}

public CriteriaBuilder getCriteriaBuilder() {
	return criteriaBuilder;
}
public void setCriteriaBuilder(CriteriaBuilder criteriaBuilder) {
	this.criteriaBuilder = criteriaBuilder;
}
public Root<T> getFrom() {
	return from;
}
public void setFrom(Root<T> from) {
	this.from = from;
}
public CriteriaQuery<?> getCq() {
	return cq;
}
public void setCq(CriteriaQuery<?> cq) {
	this.cq = cq;
}
public List<Predicate> getPredicates() {
	return predicates;
}
public void setPredicates(List<Predicate> predicates) {
	this.predicates = predicates;
}
public Predicate toPredicate(){
	 Predicate[] pre = new Predicate[predicates.size()];
	 return cq.where(predicates.toArray(pre)).getRestriction();
}

}
